package com.cms.sync.manager;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

import com.cms.sync.model.ImportChannelSyncData;
import com.cms.sync.model.ImportCpSyncData;
import com.cms.sync.model.ImportSyncData;
import com.cms.sync.model.MMSyncLog;
import com.cms.sync.service.DefaultSyncLogService;
import com.cms.sync.service.MMSyncLogServiceImpl;
import com.cms.sync.service.SyncImportDataService;
import com.cms.sync.service.SyncImportDataServiceImpl;
import com.util.MemCachedUtil;
import com.util.Singleton;
import com.util.Util;
import com.utils.queue.DefaultQueue;
import com.utils.string.EncodingUtils;
import com.utils.string.EncodingUtils.CHARSET;

public class MMSyncLogManager extends Singleton {

	public static MMSyncLogManager getInstance()
	{
		return (MMSyncLogManager) MMSyncLogManager.getInstance(MMSyncLogManager.class.getName());
	}
	
	public MMSyncLogManager(){
		List<MMSyncLog> itemlist = service.getAll();
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DATE, -2); //将时间设置为当前时间的前3天(包含今天)
		for (MMSyncLog item : itemlist) {
			if(item.getOrderid()==null||item.getOrderid().equals("null"))continue;
			String tmpKey = item.getAppid() + "_" + item.getPaycode();
			if (!relevanceAndpointCode.containsKey(tmpKey)) {
				//将对应信息添加到缓存
				relevanceAndpointCode.put(tmpKey, syncservice
						.getMessageByrelevanceIdAndpointCode(
								item.getAppid(), item.getPaycode()));
			}
			String tmpStr = relevanceAndpointCode.get(tmpKey);
			if (tmpStr != null && tmpStr.length() > 0) {
				//String[] arr = tmpStr.split(",");
				String tkey = "mm_" + item.getAppid()+"_"+ channelid;
				if (!allUid.keyExists(tkey)) {
					allUid.add(tkey, new ArrayList<String>());
				}
				ArrayList<String> al = (ArrayList<String>) allUid.get(tkey);
				al.add(item.getFeemsisdn());
				allUid.replace(tkey, al);

				//保存近3天的数据
				Date d = Util.stringToDate(
						item.getActiontime(), "yyyyMMddHHmmss");
				if (d.after(c.getTime())) {
					String tmpdate = Util.dateToString(Util.stringToDate(item.getActiontime(), "yyyyMMddHHmmss"),"yyyyMMddHHmm");
					tkey = tkey+"_"+tmpdate+"_active";
					if (!allUid.keyExists(tkey)) {
						allUid.add(tkey, new ArrayList<String>(),
								60 * 60 * 24 * 3);
					}
					ArrayList<String> al1 = (ArrayList<String>) allUid.get(tkey);
					al1.add(item.getFeemsisdn());
					allUid.replace(tkey, al1);
				}
			}
		}
		new SyncThread().start();
	}
	
	private SAXBuilder sax = new SAXBuilder();
	private Map<String,String> relevanceAndpointCode=new HashMap<String,String>();
	private DefaultSyncLogService<MMSyncLog> service = new MMSyncLogServiceImpl();
	private SyncImportDataService syncservice=new SyncImportDataServiceImpl();
	
	private DefaultQueue queue = new DefaultQueue(100);
	private MemCachedUtil allUid = MemCachedUtil.getInstance();
	//private MapUtil allUid = new MapUtil();
	private int wait = 0;
	
	private final int channelid=1008; //MM渠道 初始化
	//private final String operator="未知";
	private final String source="MM";
	private final String province="未知";
	private final String[] operator={"","中国移动","中国联通","中国电信","第三方支付"};
	
	public void saveMMSyncLog(String xmlStr){
		xmlStr = EncodingUtils.encode(xmlStr, CHARSET.ISO88591, CHARSET.UTF8);
		MMSyncLog m = new MMSyncLog();
		m.setRemark(xmlStr);
		try {
			Reader r = new StringReader(xmlStr);
			Document d = sax.build(r);
			Element e = d.getRootElement();
			Namespace n = e.getNamespace();
			m.setOrderid(e.getChildText("OrderID",n));
			m.setCheckid(e.getChildText("CheckID",n));
			m.setActiontime(e.getChildText("ActionTime",n));
			m.setActionid(e.getChildText("ActionID",n));
			m.setMsisdn(e.getChildText("MSISDN",n));
			m.setFeemsisdn(e.getChildText("FeeMSISDN",n));
			m.setAppid(e.getChildText("AppID",n));
			m.setPaycode(e.getChildText("PayCode",n));
			m.setTradeid(e.getChildText("TradeID",n));
			m.setPrice(Float.parseFloat(e.getChildText("Price",n)));
			m.setTotalprice(Float.parseFloat(e.getChildText("TotalPrice",n)));
			m.setSubsnumb(e.getChildText("SubsNumb",n));
			m.setSubsseq(e.getChildText("SubsSeq",n));
			m.setChannelid(e.getChildText("ChannelID",n));
			m.setExdata(e.getChildText("ExData",n));
			m.setOrdertype(e.getChildText("OrderType",n));
			m.setMd5sign(e.getChildText("MD5Sign",n));
			m.setOrderpayment(e.getChildText("OrderPayment",n));
			r.close();
			
		} catch (JDOMException e) {
			e.printStackTrace();
			System.out.println("[date:"+Util.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss")+"] [Class:MMSyncLogManager] [method:saveSyncLogs] [errMsg:"+e.getMessage()+"]");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("[date:"+Util.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss")+"] [Class:MMSyncLogManager] [method:saveSyncLogs] [errMsg:"+e.getMessage()+"]");
		}
		
		if(queue.isFull()){
			queue.setMaxSize(queue.getMaxSize()+50);
		}
		push(m);

		service.save(m);
	}
	
	public void push(Object obj) {
		synchronized (queue) {
			queue.push(obj);
			if (wait > 0) {
				queue.notify();
			}
		}
	}
	
	public Object pop() {
		synchronized (queue) {
			if (queue.isEmpty()) {
				wait++;
				try {
					queue.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				wait--;
			}
			return queue.pop();
		}
	}
	
	
	class SyncThread extends Thread{

		@Override
		public void run() {
			try {
				while(true){
					MMSyncLog t = (MMSyncLog) pop();
					boolean flag = saveSyncImportData(t);
					if(!flag){
						queue.push(t);
					}
					
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	
	/**
	 * MM同步添加
	 * @param t
	 * @return
	 */
	private boolean saveSyncImportData(MMSyncLog t){
		boolean flag=true;
		if(t.getOrderid()==null||t.getOrderid().equals("null"))return flag;
		int newUser=0; //新增用户数
		int activeUser=0; //活跃用户数
		int payUser=0; //付费用户数
		int payNumber=0; //付费次数
		float fee = 0;
		
		ImportSyncData importData = new ImportSyncData();

		importData.setChannelid(channelid);
		importData.setOperator(operator[Integer.parseInt(t.getOrderpayment())]);
		importData.setProvince(province);
		importData.setSource(source);
		
		try {
			//时间
			Date d = Util.stringToDate(t.getActiontime(), "yyyyMMddHHmmss");
			Calendar c = Calendar.getInstance();
			c.setTime(d);
			String day = Util.dateToString(c.getTime(), "yyyyMMdd");
			int hour= c.get(Calendar.HOUR_OF_DAY);
			int minute=c.get(Calendar.MINUTE);
			importData.setDay(Integer.valueOf(day));
			importData.setHour(hour);
			importData.setMinute(minute);
			
			String uid = t.getFeemsisdn();
			{
				String tmpKey = t.getAppid()+"_"+t.getPaycode();
				if(!relevanceAndpointCode.containsKey(tmpKey)||relevanceAndpointCode.get(tmpKey)==null){
					//将对应信息添加到缓存
					relevanceAndpointCode.put(tmpKey, syncservice.getMessageByrelevanceIdAndpointCode(t.getAppid(), t.getPaycode()));
				}
				//get appnumber cpid goodsid goodsname
				String tmpStr = relevanceAndpointCode.get(tmpKey);
				if(tmpStr!=null&&tmpStr.length()>0){
					String[] arr = tmpStr.split(",");
					String tkey = "mm_"+t.getAppid()+"_"+channelid;
					if(!allUid.keyExists(tkey)){
						allUid.add(tkey, new ArrayList<String>());
					}
					ArrayList<String> al = (ArrayList<String>)allUid.get(tkey);
					//把uid加进全局缓存
					if(!al.contains(uid))
					{
						newUser++;
						al.add(uid);
						allUid.replace(tkey, al);
					}
					
					//活跃用户
					String tmpdate = Util.dateToString(Util.stringToDate(t.getActiontime(), "yyyyMMddHHmmss"), "yyyyMMddHHmm");
					tkey=tkey+"_"+tmpdate+"_active";
					if(!allUid.keyExists(tkey)){
						allUid.add(tkey, new ArrayList<String>(),60*60*24*3);
					}
					ArrayList<String> al1 = (ArrayList<String>)allUid.get(tkey);
					if(!al1.contains(uid)){
						activeUser++;
						al1.add(uid);
						allUid.replace(tkey, al1);
					}
					
					//set appnumber cpid goodsid goodsname
					importData.setAppnumber(arr[0]); 
					importData.setCpid(Integer.parseInt(arr[1]));
					importData.setGoodsid(Integer.parseInt(arr[2]));
					importData.setGoodsname(arr[3]);
				}else{
					System.out.println("[date:"+Util.dateToString(new Date(),"yyyy-MM-dd HH:mm:ss")+"] [Class:MMSyncLogManager] [method:saveSyncImportData] [tmpStr is null] [appid:"+t.getAppid()+"] [paycode:"+t.getPaycode()+"]");
				}
				
				//付费用户  订单号不是20个0 代表成功
				if(!t.isFail()){
					payUser++;
					fee=t.getPrice();
				}
				
				payNumber++;
			}
			importData.setPaidnumber(payNumber);
			
			importData.setNewusers(newUser);
			importData.setActiveuser(activeUser);
			
			importData.setPayingcustomers(payUser);
			importData.setFee(fee);
			
			syncservice.saveImportSyncData(importData);
			syncservice.saveImportCpSyncData(new ImportCpSyncData(importData));
			syncservice.saveImportChannelSyncData(new ImportChannelSyncData(importData));
			
			System.out.println("[date:"+Util.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss")+"] [Class:Class:MMSyncLogManager] [method:method:saveSyncImportData] [SUCCESS]");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("[date:"+Util.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss")+"] [Class:MMSyncLogManager] [method:saveSyncImportData] [errMsg:"+e.getMessage()+"]");
			flag=false;
		}
		return flag;
	}
	
	public boolean isRepeatOrder(String orderId,String source){
		//处理重复订单
		return service.idRepeatOrder(orderId).size()>0;
	}
}
